package com.fruit.auth.dao.impl;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.jdbc.Work;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import com.fruit.auth.dao.RolePrivilegeDao;
import com.fruit.auth.model.Privilege;
import com.fruit.auth.model.Role;
import com.fruit.auth.model.RolePrivilege;
import com.fruit.auth.model.UserRole;
import com.fruit.dao.impl.BaseDaoImpl;

@Repository("rolePrivilegeDao")
public class RolePrivilegeDaoImpl extends BaseDaoImpl<RolePrivilege> implements RolePrivilegeDao
{

	@Override
	public void saveRolePrivileges(final Role role, final List<Serializable> privilegeIds)
	{
		final String sql="insert into AUTH_ROLE_PRIVILEGE(AUTH_ROLE_id,AUTH_PRIVILEGE_id) values(?,?)";
		getSession().doWork(new Work()
		{
			
			@Override
			public void execute(Connection connection) throws SQLException
			{
				connection.setAutoCommit(false);
				PreparedStatement stat=connection.prepareStatement(sql);
				for(Serializable id:privilegeIds)
				{
					stat.setInt(1, role.getId());
					stat.setInt(2,	(int) id);
					stat.addBatch();
				}
				stat.executeBatch();
				connection.commit();
			}
		});
		
	}

	@Override
	public UserRole findRolePrivilege(Role role, Privilege privilege)
	{
		String hql="from RolePrivilege rp left join fetch rp.role left join fetch rp.privilege where rp.role.id=? and rp.privilege.id=?";
		return (UserRole) findUniqueResultByHql(hql, role.getId(),privilege.getId());
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Privilege> findRolePrivileges(Role role)
	{
		String hql="select new RolePrivilege(id,name,privilegeEnabled,parent) from RolePrivilege rp where rp.role.id=?";
		return getSession().createQuery(hql).setParameter(1, role.getId()).list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Serializable> findRolePrivilegeIds(Role role)
	{
		String hql="select rp.privilege.id from RolePrivilege rp where rp.role.id=?0";
		return getSession().createQuery(hql).setParameter("0", role.getId()).list();
	}

	public void updateRolePrivileges(final Role role,List<Serializable> privilegeIds)
	{
		//判断角色privilegeIds是否为空，如果为空则说明未分配任何权限，则清空数据库该用户所有已有权限关系
		if(CollectionUtils.isEmpty(privilegeIds))
		{
			unAuthRolePrivileges(role);
		}
		else
		{
			//找到该角色所有已有权限的id
			List<Serializable> db_privilegeIds=findRolePrivilegeIds(role);
			//如果在数据库中该角色没有任何权限，页面上分配了权限，则直接保存新分配的所有权限
			if(CollectionUtils.isEmpty(db_privilegeIds))
			{
				saveRolePrivileges(role, privilegeIds);
			}
			else
			{
				//数据库里该用户已经存在的权限不全部包含页面分配的权限，说明有新权限分配，要插入
				if(!db_privilegeIds.containsAll(privilegeIds))
				{
					List<Serializable> newPrivilegeIds=new ArrayList<Serializable>();
					for(Serializable privilegeId:privilegeIds)
					{
						//如果该分配的权限在数据库中没有则添加
						if(!db_privilegeIds.contains(privilegeId))
						{
							newPrivilegeIds.add(privilegeId);
						}
					}
					//保存新分配的权限
					saveRolePrivileges(role, newPrivilegeIds);
				}
				
				final StringBuilder sb=new StringBuilder();
				//该用户在页面分配的权限不全部包含数据库中该角色已有权限，即用户在页面上删除了该角色的某些权限
				if(!privilegeIds.containsAll(db_privilegeIds))
				{
					sb.append("delete from AUTH_Role_Privilege where AUTH_ROLE_id=? and AUTH_PRIVILEGE_id in(");
					for(Serializable db_privilegeId:db_privilegeIds)
					{
						//数据库中的该角色的权限在页面上没有分配，准备删除该已有权限
						if(!privilegeIds.contains(db_privilegeId))
						{
							sb.append(db_privilegeId).append(",");
						}
					}
					final String sql=sb.deleteCharAt(sb.length()-1).append(")").toString();
					getSession().doWork(new Work()
					{
						
						@Override
						public void execute(Connection connection) throws SQLException
						{
							connection.setAutoCommit(false);
							PreparedStatement stat=connection.prepareStatement(sql);
							stat.setInt(1, role.getId());
							stat.executeUpdate();
							stat.close();
						}
					});
				}
			}
		}
	}
	
	
	public void unAuthRolePrivileges(Role role)
	{
		String hql="delete from RolePrivilege rp where rp.role=?";
		batchEntityByHql(hql, role);
		
	}
	//解除多个角色与权限的关系
	public void unAuthRolesPrivileges(String roleIdsStr)
	{
		StringBuilder deleteRolePrivilegesSql=new StringBuilder();
		deleteRolePrivilegesSql.append("delete from AUTH_ROLE_PRIVILEGE where AUTH_ROLE_id in(");
		deleteRolePrivilegesSql.append(roleIdsStr).append(")");
		executeUpdateSql(deleteRolePrivilegesSql.toString());
	}
	
	
}
